﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Collections.ObjectModel;
using System.Text.RegularExpressions;
using System.Globalization;
using System.Threading;

namespace WatiN.Samples.Console
{
    public class UserInfo
    {
        public string user_id;
        public string user_name;
        public bool full;
        public bool user_flg; //online?
        public string xnid;
    }

    public class CarInfo
    {
        //"park_type":0,"user_id":4418080,"user_name":"\u6c64\u8001\u5e08","car_style":20,"car_id":2,"car_icon":"lingmu0","money":"290","park_site_id":17795925,"uc_id":18481934,"car_name":"\u90fd\u5e02\u8d1d\u8d1d"
        public int park_type;
        public string user_id;
        public string user_name;
        public int car_style;
        public int car_id;
        public string car_icon;
        public string money;
        public string park_site_id;
        public string uc_id;
        public string car_name;
    }

    public class ParkList
    {
        //{"free":0,"mobile":0,"type":1,"car_owner_id":4415946,"money":620,"id":17797405,"parked":1,"car_name":"\u4e8c\u624b\u5965\u62d3","car_icon":"lingmu0","car_style":1,"car_id":18126467,"friend":0,"head":"http:\/\/hd54.xiaonei.com\/photos\/hd54\/20081016\/09\/53\/tiny_T4ox_539j200150.jpg","car_price":10000,"name":"\u55bb\u658c"}
        public int free;
        public int mobile;
        public int type;
        public string car_owner_id;
        public int money;
        public string id;
        public int parked;
        public string car_name;
        public string car_icon;
        public int car_style;
        public string car_id;
        public int friend;
        public string head;
        public int car_price;
        public string name;
    }

    public class ParkInfo
    {
        public string sceneName;
        public ParkList[] parklist = new ParkList[4];
        //public Collection<ParkInfo> _parkInfoList;
        public string sceneBg;
        public string background;
        public string sceneRoad;
        public string name;
        public string tiny_url;
        public string id;
        public int mypark;
    }

    public class ParkerContent
    {
        private const string RET_AJAXPREADDCAR_OK = "{\"free\":";
        private const string RET_AJAXADDCAR_OK = "{\"park_id\":";
        private const string RET_AJAXADDCAR_TIMENOTENOUGH = "timeNotEnough";
        private const string RET_AJAXPREADDCAR_REPARK = "rePark";
        private const string RET_AJAXPREADDCAR_ERROR = "err";
        private const string RET_AJAXREMOVECAR_OK = "{\"park_id\":";

        public Collection<UserInfo> _friendList = new Collection<UserInfo>();
        public Collection<string> _friendIdList = new Collection<string>();
        public Collection<CarInfo> _carInfoList = new Collection<CarInfo>();
        //public Collection<ParkInfo> _parkInfoList = new Collection<ParkInfo>();
        public ParkInfo _parkInfo = new ParkInfo();
        public string _ownerId = string.Empty;
        public string _ownerMoney = string.Empty;

        private string GetKeyValue(string text, string key, string split)
        {
            string value = string.Empty;
            int pos1 = text.IndexOf(key);
            if (pos1 >= 0)
            {
                int pos2 = text.IndexOf(split, pos1);
                if (pos2 >= 0)
                {
                    value = text.Substring(pos1 + key.Length, pos2 - pos1 - key.Length);
                }
            }
            return value;
        }

        private CarInfo GetCarInfo(string text)
        {
            CarInfo ci = new CarInfo();
            string key = "\"park_type\":";
            ci.park_type = SafeConvert.ToInt32(GetKeyValue(text, key, ","));
            key = "\"user_id\":";
            ci.user_id = GetKeyValue(text, key, ",");
            key = "\"user_name\":";
            ci.user_name = U2CnCode(GetKeyValue(text, key, ","));
            key = "\"car_style\":";
            ci.car_style = SafeConvert.ToInt32(GetKeyValue(text, key, ","));
            key = "\"car_id\":";
            ci.car_id = SafeConvert.ToInt32(GetKeyValue(text, key, ","));
            key = "\"car_icon\":";
            ci.car_icon = GetKeyValue(text, key, ",");
            key = "\"money\":";
            ci.money = GetKeyValue(text, key, ",");
            key = "\"park_site_id\":";
            ci.park_site_id = GetKeyValue(text, key, ",");
            key = "\"uc_id\":";
            ci.uc_id = GetKeyValue(text, key, ",");
            key = "\"car_name\":";
            ci.car_name = U2CnCode(GetKeyValue(text, key, "}"));

            return ci;
        }

        public void GetCarlist(string text)
        {
            _carInfoList.Clear();

            string key = "\"carlist\":[";
            string carlist = GetKeyValue(text, key, "]");
            string[] carinfos = carlist.Split(new Char[] { '{' });
            foreach (string carinfo in carinfos)
            {
                if (String.IsNullOrEmpty(carinfo))
                    continue;
                CarInfo ci = GetCarInfo(carinfo);
                _carInfoList.Add(ci);
            }
        }

        private ParkList GetParkList(string parkinfo)
        {
            ParkList pi = new ParkList();
            string key = "\"free\":";
            pi.free = SafeConvert.ToInt32(GetKeyValue(parkinfo, key, ","));
            key = "\"mobile\":";
            pi.mobile = SafeConvert.ToInt32(GetKeyValue(parkinfo, key, ","));
            key = "\"type\":";
            pi.type = SafeConvert.ToInt32(GetKeyValue(parkinfo, key, ","));
            key = "\"car_owner_id\":";
            pi.car_owner_id = GetKeyValue(parkinfo, key, ",");
            key = "\"money\":";
            pi.money = SafeConvert.ToInt32(GetKeyValue(parkinfo, key, ","));
            key = "\"id\":";
            pi.id = GetKeyValue(parkinfo, key, ",");
            key = "\"parked\":";
            if (!String.IsNullOrEmpty(pi.car_owner_id))
                pi.parked = SafeConvert.ToInt32(GetKeyValue(parkinfo, key, ","));
            else
                pi.parked = SafeConvert.ToInt32(GetKeyValue(parkinfo, key, "}"));
            key = "\"car_name\":";
            pi.car_name = U2CnCode(GetKeyValue(parkinfo, key, ","));
            key = "\"car_icon\":";
            pi.car_icon = GetKeyValue(parkinfo, key, ",");
            key = "\"car_style\":";
            pi.car_style = SafeConvert.ToInt32(GetKeyValue(parkinfo, key, ","));
            key = "\"car_id\":";
            pi.car_id = GetKeyValue(parkinfo, key, ",");
            key = "\"friend\":";
            pi.friend = SafeConvert.ToInt32(GetKeyValue(parkinfo, key, ","));
            key = "\"head\":";
            pi.head = GetKeyValue(parkinfo, key, ",");
            key = "\"car_price\":";
            pi.car_price = SafeConvert.ToInt32(GetKeyValue(parkinfo, key, ","));
            key = "\"name\":";
            pi.name = U2CnCode(GetKeyValue(parkinfo, key, "}"));

            return pi;
        }

        private void GetParklist(string parkinfo)
        {
            string key = "\"parklist\":[";
            string lists = GetKeyValue(parkinfo, key, "]");
            string[] parklists = lists.Split(new Char[] { '{' });
            _parkInfo.parklist[0] = GetParkList(parklists[1]);
            _parkInfo.parklist[1] = GetParkList(parklists[2]);
            _parkInfo.parklist[2] = GetParkList(parklists[3]);
            _parkInfo.parklist[3] = GetParkList(parklists[4]);
        }

        public void GetParkInfo(string parkinfo)
        {
            string key = "\"sceneName\":";
            _parkInfo.sceneName = U2CnCode(GetKeyValue(parkinfo, key, ","));
            GetParklist(parkinfo);

            key = "\"sceneBg\":";
            int pos = parkinfo.IndexOf(key);
            string text = parkinfo.Substring(pos);
            _parkInfo.sceneBg = GetKeyValue(text, key, ",");
            key = "\"background\":";
            _parkInfo.background = GetKeyValue(text, key, ",");
            key = "\"sceneRoad\":";
            _parkInfo.sceneRoad = GetKeyValue(text, key, ",");
            key = "\"name\":";
            _parkInfo.name = U2CnCode(GetKeyValue(text, key, ","));
            key = "\"tiny_url\":";
            _parkInfo.tiny_url = GetKeyValue(text, key, ",");
            key = "\"id\":";
            _parkInfo.id = GetKeyValue(text, key, ",");
            key = "\"mypark\":";
            _parkInfo.mypark = SafeConvert.ToInt32(GetKeyValue(text, key, "}"));
        }

        public static string GetContentMid(string str, int startPos, string start, string end, out int pos)
        {
            pos = -1;
            if (str == null)
            {
                return null;
            }
            int posStart = str.IndexOf(start, startPos);
            if (-1 == posStart)
            {
                return null;
            }

            posStart += start.Length;
            int posEnd = str.IndexOf(end, posStart);
            if (-1 == posEnd)
            {
                return null;
            }

            pos = posEnd;

            return str.Substring(posStart, posEnd - posStart);
        }

        public static string GetContentMid(string str, string start, string end, out int pos)
        {
            return GetContentMid(str, 0, start, end, out pos);
        }

        public void GetFriendList(string content)
        {
            int pos;
            string friendlist = GetContentMid(content, "eval('friends='+'{\"friends\":[{", "\n", out pos);
            if (String.IsNullOrEmpty(friendlist))
            {
                TraceLog.Error("未读到朋友列表数据，请务必手工登陆停一次车后，再使用！");
                return;
            }
            string pagedata = GetContentMid(content, "eval('pageData='+'", "\n", out pos);
            if (String.IsNullOrEmpty(pagedata))
            {
                TraceLog.Error("未读到用户自身数据，请务必手工登陆停一次车后，再使用！");
                return;
            }
            _ownerId = GetKeyValue(pagedata, "\"id\":", "}");
            string moneyData = GetContentMid(content, "flashvars.money = ", "\n", out pos);
            if (String.IsNullOrEmpty(moneyData))
            {
                TraceLog.Error("未读到用户的现金数据，请务必手工登陆停一次车后，再使用！");
                return;
            }
            _ownerMoney = GetKeyValue(moneyData, "'", "';");

            _friendList.Clear();
            _friendIdList.Clear();
            string[] friends = friendlist.Split(new Char[] { '{' });
            foreach (string friend in friends)
            {
                UserInfo ui = new UserInfo();
                string key = "\"userid\":";
                ui.user_id = GetKeyValue(friend, key, ",");
                key = "\"user_flg\":";
                ui.user_flg = (GetKeyValue(friend, key, ",") == "\"f\"");
                key = "\"user_name\":";
                ui.user_name = U2CnCode(GetKeyValue(friend, key, ","));
                key = "\"full\":";
                ui.full = (GetKeyValue(friend, key, ",") == "\"f\"");
                key = "\"xnid\":";
                ui.xnid = GetKeyValue(friend, key, "}");
                //string friendType = IsNeighbor(JsonHelper.GetIntegerValue(user["neighbor"])) ? "邻居" : "好友";
                //TraceLog.PrintLn(string.Format(" #{0}: {1}({2}) {3}", ++no, friend.Name, friend.Id, friend.Full ? "车位满" : ""));

                _friendList.Add(ui);
                _friendIdList.Add(ui.user_id);
            }
        }

        public static string U2CnCode(string str)
        {
            Match m;
            Regex r = new Regex("(?<code>\\\\u[a-z0-9]{4})",RegexOptions.IgnoreCase );
            for (m = r.Match(str); m.Success; m = m.NextMatch())
            {
                string strValue = m.Result("${code}");   //代码
                int CharNum = Int32.Parse(strValue.Substring(2, 4), System.Globalization.NumberStyles.HexNumber);
                string ch =string.Format("{0}",(char)CharNum);
                str = str.Replace(strValue, ch);
            }
            return str;
        }

        public void DoPost(HttpHelper _hh)
        {
            string content = _hh.Post("http://carpark.xiaonei.com/ajax_car_park_get_next_page.f", "pid=" + _ownerId);
            Thread.Sleep(ConfigHelper.SLEEP_TIME);
            GetParkInfo(content);

            //TraceLog.Print("Parking... ");
            for (int i = 0; i < 4; i++)
            {
                if (_parkInfo.parklist[i].free == 0 && _parkInfo.parklist[i].parked == 1)
                {
                    //"http://carpark.xiaonei.com/ajax_car_park_remove_car.do?pid=1&_="
                    content = _hh.Post("http://carpark.xiaonei.com/ajax_car_park_remove_car.do", "pid=" + i + "&_=");
                    if (content.StartsWith(RET_AJAXREMOVECAR_OK))
                    {
                        TraceLog.PrintLn(String.Format("开始贴条...#{0}成功贴条!", i));
                    }
                    else
                    {
                        TraceLog.PrintLn(String.Format("开始贴条...#{0}无法贴条!", i));
                    }
                }
            }
        }

        public void DoReport(string carOnlyId, string reportManIdTo, string parkOnlyId, HttpHelper _hh)
        {
            //"http://carpark.xiaonei.com/ajaxCallThePolice.do?carOnlyId=18962115&reportManIdTo=4418109&parkOnlyId=17795925&_="
            string content = _hh.Post("http://carpark.xiaonei.com/ajaxCallThePolice.do", "carOnlyId=" + carOnlyId + "&reportManIdTo=" + reportManIdTo + "&parkOnlyId=" + parkOnlyId + "&_=");
        }

        public void DoParking(CarInfo car, HttpHelper _hh)
        {
            foreach (UserInfo friend in _friendList)
            {
                TraceLog.PrintLn(String.Format("获取好友信息: {0}的车位{1}位.", friend.user_name, friend.full ? "满" : "有空"));
                if (friend.full)
                    continue;

                string content = String.Empty;
                string pid = friend.user_id;
                content = _hh.Post("http://carpark.xiaonei.com/ajax_car_park_get_next_page.f", "pid=" + pid);
                Thread.Sleep(ConfigHelper.SLEEP_TIME);
                GetParkInfo(content);

                //TraceLog.Print("Parking... ");
                for (int i = 0; i < 4; i++)
                {
                    if (_parkInfo.parklist[i].free != 1 && _parkInfo.parklist[i].parked != 1)
                    {
                        string parkOwnerIdTo = friend.user_id;
                        string parkOwnerNameTo = HttpHelper.EncodePostData(friend.user_name.Replace("\"", ""));
                        string parkIdTo = i.ToString();
                        string ownerId = _ownerId;
                        content = _hh.Post("http://carpark.xiaonei.com/ajaxPreAddCar.do", "parkOwnerIdTo=" + parkOwnerIdTo +
                            "&parkOwnerNameTo=" + parkOwnerNameTo +
                            "&parkIdTo=" + parkIdTo +
                            "&ownerId=" + ownerId + "&_=");
                        Thread.Sleep(ConfigHelper.SLEEP_TIME);
                        if (content.StartsWith(RET_AJAXPREADDCAR_OK))
                        {
                            string parkOwnerIdFrom = (car.user_id == String.Empty ? "0" : car.user_id);
                            string parkIdFrom = "0";
                            string carId = car.car_id.ToString();
                            string onlyCarId = car.uc_id;
                            string carName = HttpHelper.EncodePostData(car.car_name.Replace("\"", ""));
                            string parkOwnerNameFrom = HttpHelper.EncodePostData(car.user_name.Replace("\"", ""));
                            content = _hh.Post("http://carpark.xiaonei.com/ajaxAddCar.do", "parkOwnerIdFrom=" + parkOwnerIdFrom +
                                "&parkIdFrom=" + parkIdFrom +
                                "&parkOwnerNameTo=" + parkOwnerNameTo +
                                "&parkOwnerIdTo=" + parkOwnerIdTo +
                                "&parkIdTo=" + parkIdTo +
                                "&carId=" + carId +
                                "&ownerId=" + ownerId +
                                "&free=0&onlyCarId=" + onlyCarId +
                                "&carName=" + carName +
                                "&parkOwnerNameFrom=" + parkOwnerNameFrom + "&_=");
                            Thread.Sleep(ConfigHelper.SLEEP_TIME);
                            if (content.StartsWith(RET_AJAXADDCAR_OK))
                            {
                                TraceLog.PrintLn(String.Format("开始停车...#{0}:{1}=>{2}({3})成功停车!", carId, car.car_name.Replace("\"", ""), friend.user_name.Replace("\"", ""), parkOwnerIdTo));
                                return;
                            }
                            if ((content == RET_AJAXADDCAR_TIMENOTENOUGH))
                            {
                                TraceLog.PrintLn(String.Format("开始停车...#{0}:{1}=>{2}({3})停车不足15分钟!", carId, car.car_name.Replace("\"", ""), friend.user_name.Replace("\"", ""), parkOwnerIdTo));
                                return;
                            }
                            if (content == RET_AJAXPREADDCAR_ERROR)
                            {
                                TraceLog.PrintLn(String.Format("开始停车...#{0}:{1}=>{2}({3})停车失败!", carId, car.car_name.Replace("\"", ""), friend.user_name.Replace("\"", ""), parkOwnerIdTo));
                                break;
                            }
                            //TraceLog.PrintLn("ajaxAddCar failed, repark!");
                        }
                        //else
                        //{
                            //TraceLog.PrintLn("ajaxPreAddCar failed, repark!");
                        //}
                        //TraceLog.PrintLn("Repark!");
                    }
                }
            }
        }
    }
}
